//
//  GroupsArrayController.m
//  Words2
//
//  Created by Mathieu Tozer on 11/09/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//



#import "GroupsArrayController.h"
#import "WordMO.h"
#import "Group.h"
#import "WordsAppDelegate.h"
#import "ControllerData.h"
#import "LanguageArrayController.h"
#define WordType @"Word"
#define GroupType @"Group"


//all this one does is the drag and drops

@implementation GroupsArrayController
- (void)awakeFromNib {
    // register for drag and drop
    [tableView registerForDraggedTypes:
		[NSArray arrayWithObjects:WordType, nil]];
	
	//register for notifications
	[self registerAsObserver];
	[super awakeFromNib];
}

- (void)registerAsObserver{
    [self addObserver:self
		   forKeyPath:@"selection"
			  options:(NSKeyValueObservingOptionNew |
					   NSKeyValueObservingOptionOld)
			  context:NULL];
	[self addObserver:self
		   forKeyPath:@"arrangedObjects"
			  options:(NSKeyValueObservingOptionNew |
					   NSKeyValueObservingOptionOld)
			  context:NULL];
}

//if the selection of self changes, then save the new selection
- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object 
                        change:(NSDictionary *)change
                       context:(void *)context{
    if (object == self && [keyPath isEqual:@"selection"]) {
		
		[self selectionWillChange];
		
		// the same change
		[super observeValueForKeyPath:keyPath
							 ofObject:object 
							   change:change 
							  context:context];
	}

	//if the language selection changes, then load the saved selection.
	if (object == self && [keyPath isEqual:@"arrangedObjects"]) {
		
		[self languageSelectionDidChange];
		
		// the same change
		[super observeValueForKeyPath:keyPath
							 ofObject:object 
							   change:change 
							  context:context];
	}
}

-(void)languageSelectionDidChange{
	//set the selected group to whatever was selected before
	NSURL *languageURI = [[[[languageArrayController selectedObjects] objectAtIndex:0] objectID] URIRepresentation];
	NSURL *groupURI = [currentLanguageGroupSelection objectForKey:languageURI];
	if(groupURI != nil){
		NSManagedObjectContext *moc = [[NSApp delegate] managedObjectContext];
		NSPersistentStoreCoordinator *psc = [moc persistentStoreCoordinator]; 
		Group *groupToSelect = [moc objectWithID:[psc managedObjectIDForURIRepresentation:groupURI]];
		[self setSelectedObjects:[NSArray arrayWithObject:groupToSelect]];
	}else{
		//just set it to library
		[self setSelectionToLibrary];
	}
	
}

#pragma mark Group Add / Delete

-(IBAction)addSmart:(id)sender{
	//create the new smartgroup
	SmartGroup *newSmartGroup = [NSEntityDescription insertNewObjectForEntityForName:@"SmartGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[self addObject:newSmartGroup];
}

-(IBAction)addManual:(id)sender{
	//create the new manual
	SmartGroup *newManualGroup = [NSEntityDescription insertNewObjectForEntityForName:@"ManualGroup" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
	[self addObject:newManualGroup];
	[self rearrangeObjects];
}

- (void)addObject:(id)object{
	[super addObject:object];
}

-(void)remove:(id)sender{
	//I will have to get the selection, search for it in the appropriate array, and remove it with the array controller's remove method
	Group *selectedGroup = [[self selectedObjects] objectAtIndex:0];
	
	if([selectedGroup isThisGroupTheLibrary]){
		NSBeep();
		NSLog(@"Cannot delete the library.");
	}
	else{
		[super removeObject:selectedGroup];
	}	
}


-(void)selectionWillChange{
	if(!currentLanguageGroupSelection){
		currentLanguageGroupSelection = [[NSApp delegate] languageGroupControllerSelectionSaver];
	}		
	[currentLanguageGroupSelection setObject:[[[[self selectedObjects] objectAtIndex:0] objectID] URIRepresentation] forKey:[[[[NSApp delegate] currentlySelectedLanguage] objectID] URIRepresentation]];

}

-(void)setSelectionToLibrary{
	//iterate through the array to find the library object.
	NSArray *groups = [self arrangedObjects];
	NSEnumerator *e = [groups objectEnumerator];
	Group *nextGroup;
	while(nextGroup = [e nextObject]){
		if([nextGroup isThisGroupTheLibrary]){
			break;
		}
	}
	[self setSelectedObjects:[NSArray arrayWithObject:nextGroup]];
}

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes 
	 toPasteboard:(NSPasteboard*)pboard {
    // Copy the row numbers to the pasteboard.
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
    [pboard declareTypes:[NSArray arrayWithObject:GroupType] owner:self];
    [pboard setData:data forType:GroupType];
	
    return YES;
}

/*When a drag operation enters a table view, the table view sends a 
tableView:validateDrop:proposedRow:proposedDropOperation: message to 
its data source. If this method is not implemented or if the method returns 
NSDragOperationNone, the drag operation is not allowed.*/
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op 
{
    // Add code here to validate the drop
    NSDragOperation dragOp = NSDragOperationLink;
    
    // if drag source is self, it's a move
    if ([info draggingSource] == tableView) {
		dragOp =  NSDragOperationMove;
    }
	if([[[self arrangedObjects] objectAtIndex:row] isManualGroup]){
		[tv setDropRow:row dropOperation:NSTableViewDropOn];
	}
	else{
		dragOp = NSDragOperationNone;
	}
    return dragOp; 
	
}

/*When a validated drag operation is dropped onto a table view, 
the table view sends a tableView:acceptDrop:row:dropOperation: message to its data source. 
The data source's implementation of this method should incorporate the data from the 
dragging pasteboard (obtained from the acceptDrop parameter) and use the other parameters 
to update the table. For example, if the drag operation type (also obtained from the 
															  acceptDrop parameter) was NSDragOperationMove and the drag originated from the table, 
you would want to move the row from its old location to the new one.*/

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info 
			  row:(int)row dropOperation:(NSTableViewDropOperation)operation {
	
	NSPasteboard* pboard = [info draggingPasteboard];
	NSData* rowData = [pboard dataForType:WordType];
	NSIndexSet* indexSet = [NSKeyedUnarchiver unarchiveObjectWithData:rowData];
	
	int	index = [indexSet lastIndex];
	Group *theGroup = [[self arrangedObjects] objectAtIndex:row];
	WordMO *nextWord;
	NSMutableSet *bagOfWords;
	while (NSNotFound != index) {
		nextWord = [[wordController arrangedObjects] objectAtIndex:index];
		bagOfWords = [theGroup mutableSetValueForKey:@"words"]; //get the manual group's bag o' words
		[bagOfWords addObject:nextWord];
		index = [indexSet indexLessThanIndex:index];
	}
	
	return YES;

	
}

@end
